package com.tianji.promotion.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.StringUtils;
import com.tianji.promotion.domain.dto.CouponFormDTO;
import com.tianji.promotion.domain.po.Coupon;
import com.tianji.promotion.domain.po.CouponScope;
import com.tianji.promotion.domain.query.CouponQuery;
import com.tianji.promotion.domain.vo.CouponPageVO;
import com.tianji.promotion.mapper.CouponMapper;
import com.tianji.promotion.service.ICouponScopeService;
import com.tianji.promotion.service.ICouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券的规则信息 服务实现类
 * </p>
 *
 * @author LYY
 * @since 2025-05-17
 */
@Service
@RequiredArgsConstructor
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {
private final ICouponScopeService couponScopeService;
    @Override
    public void saveCoupon(CouponFormDTO dto) {
        //dto转po 保存优惠卷 coupon表
        Coupon coupon = BeanUtils.copyBean(dto, Coupon.class);
        this.save(coupon);
        //判断是否限定了范围 dto.specific
        if (!dto.getSpecific()) {
            return;
        }
        //如果dto.specific为true 需要校验dto.scopes
        List<Long> scopes = dto.getScopes();
        if (CollUtils.isEmpty(scopes)) {
            throw new BadRequestException("分类id不能为空");
        }
        //保存优惠券的限定范围 coupon_scope

        List<CouponScope> csList = scopes
                .stream()
                .map(aLong -> new CouponScope().setCouponId(coupon.getId())
                        .setBizId(aLong)
                        .setType(1))
                .collect(Collectors.toList());
        couponScopeService.saveBatch(csList);
    }

    @Override
    public void updateCouponById(CouponFormDTO dto, Long id) {
        // 校验参数
        Long dtoId = dto.getId();
        if ((dtoId != null && id != null && !dtoId.equals(id)) || (dtoId == null && id == null)) {
            throw new BadRequestException("参数错误");
        }
        // 更新优惠券基本信息
        Coupon coupon = BeanUtils.copyBean(dto, Coupon.class);
        // 只更新状态为1的优惠券基本信息，如果失败则是状态已修改
        boolean update = lambdaUpdate().eq(Coupon::getStatus, 1).update(coupon);
        // 基本信息更新失败则无需更新优惠券范围信息
        if (!update) return;
        //  更新优惠券范围信息
        List<Long> scopeIds = dto.getScopes();
        // 优惠券不满减，或优惠券范围为空，则不更新优惠券范围信息
        // 先删除优惠券范围信息，再重新插入
        List<Long> ids = couponScopeService.lambdaQuery()
                .select(CouponScope::getId).eq(CouponScope::getCouponId, dto.getId()).list()
                .stream().map(CouponScope::getId).collect(Collectors.toList());
        couponScopeService.removeByIds(ids);
        // 删除成功后，并且有范围再插入
        if (CollUtils.isNotEmpty(scopeIds)) {
            List<CouponScope> lis = scopeIds.stream()
                    .map(i -> new CouponScope().setCouponId(dto.getId()).setType(1).setBizId(i))
                    .collect(Collectors.toList());
            couponScopeService.saveBatch(lis);
        }
    }

    @Override
    public PageDTO<CouponPageVO> queryCouponPage(CouponQuery query) {
        //分页查询优惠券表 coupon
        Page<Coupon> page = this.lambdaQuery()
                .eq(query.getType() != null, Coupon::getDiscountType, query.getType())
                .eq(query.getStatus() != null, Coupon::getStatus, query.getStatus())
                .like(StringUtils.isNotBlank(query.getName()), Coupon::getName, query.getName())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<Coupon> records = page.getRecords();
        if (CollUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }

        //封装vo返回
        List<CouponPageVO> voList = BeanUtils.copyList(records, CouponPageVO.class);
        return PageDTO.of(page,voList);
    }

    @Override
    public void deleteById(Long id) {
        
    }

}